#include "crypt.h"
// 报表模板加密
#include <algorithm>
#include "encdec.h"
//
int keySize = 16;

// 秘钥
unsigned char key[] = {0x15, 0x17, 0x38, 0x19, 0x55, 0x46, 0xE2, 0xD1, 0xD9, 0xDA};

void generate_key(char *securityKey, int securityKeyLen)
{

    int len = sizeof(key) / sizeof(key[0]);
    for (int i = 0; i < securityKeyLen; i++)

    {
        securityKey[i] = i ^ key[i % len];
    }
}

// 报表模板加密
int encrypt(char *srcData, char *result, int Len)
{

    char securityKey[keySize];
    generate_key(securityKey, keySize);

    for (size_t i = 0; i < Len; i++)
    {
        result[i] = srcData[i] ^ securityKey[i % keySize];
    }

    return 0;
}

TokenManager::TokenManager(const char *token_dir)
{

       this->token=nullptr;


    char path_tmp[256] = {0};
    getTokenPath(token_dir, path_tmp, 256);

    this->token_path = path_tmp;

    this->parse_token();
    this->last_time = time(nullptr);
}

TokenManager::~TokenManager()
{
  
    if (this->token != nullptr)
    {
        delete this->token;
    }
}

int TokenManager::parse_token()
{

    const char *destpath = this->token_path.c_str();
    printf("token path:%s\n", destpath);
    FILE *fp = fopen(destpath, "rb");

    if (fp == nullptr)
    {
        printf("open file failed %s\n", this->token_path.c_str());
        return 0;
    }

    token_s * token = (token_s *)calloc(sizeof(token_s),1);


    fread((void *)token, sizeof(token_s), 1, fp);

    for (size_t i = 0; i < sizeof(token_s); i++)
    {

   printf("%02X ",  reinterpret_cast<unsigned char * >(token)[i]);

    }
    

    if (fp != nullptr)
    {
        fclose(fp);
       
    }

    int ret = rsa_sha256_verify((unsigned char *)token, sizeof(token_s) - SIGNATURE_LEN, token->signature,SIGNATURE_LEN);

    if (ret == 1)
    {

        this->token=token;
        printf("verify success\n");

        printf("begin_time:%d\n", this->token->begin_time);
        printf("end_time:%d\n", this->token->end_time);
        printf("run_time:%d\n", this->token->run_time);

        return 1;
    }
    else
    {

        printf("verify failed\n");
        free(token);
         this->token=nullptr;

        return 0;
    }
}

int TokenManager::update_token()
{

    time_t current_time = time(nullptr);
    time_t run_time = current_time - this->last_time;
    this->last_time = current_time;
    this->token->run_time += run_time;

    unsigned char *signature = nullptr;
    int siglen = rsa_sha256_sign((unsigned char *)this->token, sizeof(token_s) - SIGNATURE_LEN, &signature);

    memset(this->token->signature, 0, SIGNATURE_LEN);
    memcpy_s(this->token->signature, SIGNATURE_LEN, signature, siglen);

    write_token();

    return 0;
}

int TokenManager::token_expire()
{

    if (this->token == nullptr)
    {
        return 0;
    }

    this->token->begin_time = 0;
    time_t current_time = time(nullptr);
    if (this->token->end_time < current_time || this->token->begin_time > current_time)
    {
        return 1;
    }

    if (this->token->end_time - this->token->begin_time - this->token->run_time < 0)
    {
        return 1;
    }

    return 0;
}

void TokenManager::write_token()
{

    FILE *fp = fopen(this->token_path.c_str(), "wb+");
    if (fp == nullptr)
    {
        printf("open file failed %s\n", this->token_path.c_str());
        return;
    }

    fwrite((void *)&this->token, sizeof(token_s), 1, fp);
    if (fp != nullptr)
    {
        fclose(fp);
    }
}

void getTokenPath(const char *path, char *dest, int dest_len)
{

    size_t len = strlen(path);
    memcpy_s(dest, dest_len, path, len);

    if (path[len - 1] != '\\')
    {
        dest[len] = '\\';
    }

    const char *keyname = "client.key";
    strncat(dest, keyname, strlen(keyname));
}

int create_token(const char *path, int days)
{

    char path_tmp[256] = {0};

    getTokenPath(path, path_tmp, 256);

    if (days <= 0)
    {
        printf("days must be greater than 0");
        return -1;
    }

    token_s _token={0};
    _token.begin_time = time(NULL);
    _token.run_time = 0L;
    _token.end_time = days * 24 * 60 * 60 + _token.begin_time;



    unsigned char *signature;

    int siglen = rsa_sha256_sign((const unsigned char *)&_token, sizeof(token_s) - SIGNATURE_LEN, (unsigned char **)&signature);

    

    printf("siglen :%d,tokenlen:%d\n", siglen, sizeof(token_s));
      printf("====================");

    if (siglen <= SIGNATURE_LEN)
    {

        memcpy(_token.signature, signature, siglen);

        if (signature != nullptr)
        {

            delete[] signature;
        }

        printf("create_token:%d,%d,%s\n", _token.begin_time, _token.end_time, _token.signature);

 for (size_t i = 0; i < sizeof(token_s); i++)
    {
   printf("%02X ",  reinterpret_cast<unsigned char * >(&_token)[i]);

    }
        FILE *fp = fopen(path_tmp, "wb+");
        fwrite((void *)&_token, sizeof(token_s), 1, fp);
        if (fp != nullptr)
        {
            fclose(fp);
        }
    }
    else
    {

        printf("create_token failed");
    }

    return 0;
}